package org.example.demo1.service;

import io.fabric8.kubernetes.api.model.*;
import io.fabric8.kubernetes.client.Config;
import io.fabric8.kubernetes.client.ConfigBuilder;
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientBuilder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.demo1.config.MonitorConfig;
import org.springframework.http.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
@RequiredArgsConstructor
public class MonitorService {
    private static final long METRIC_COLLECTION_INTERVAL_SECONDS = 20;
    private static final long METRIC_COLLECTION_INTERVAL_MS = METRIC_COLLECTION_INTERVAL_SECONDS * 1000;

    private final MonitorConfig monitorConfig;
    private final RestTemplate restTemplate;

    private static class CpuSample {
        Map<String, Map<String, Map<String, Double>>> instanceCpuModeValue = new HashMap<>(); // instance -> cpu -> mode -> value
        long timestamp;
    }

    private CpuSample[] cpuSamples = new CpuSample[2]; // [0]旧, [1]新
    private Map<String, Double> memTotalCache = new HashMap<>(); // instance -> MemTotal
    private Map<String, Double> memAvailableCache = new HashMap<>(); // instance -> MemAvailable
    // 新增网络指标缓存
    private final Map<String, Double[]> netRxCache = new HashMap<>(); // instance -> [old, new]
    private final Map<String, Double[]> netTxCache = new HashMap<>(); // instance -> [old, new]

    public List<Map<String, Object>> getGrafanaDashboards() {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + monitorConfig.getGrafana().getApiKey());
            String url = monitorConfig.getGrafana().getUrl() + "/api/search?type=dash-db";
            ResponseEntity<List<Map<String, Object>>> response = restTemplate.exchange(
                    url,
                    HttpMethod.GET,
                    new HttpEntity<>(headers),
                    new org.springframework.core.ParameterizedTypeReference<List<Map<String, Object>>>() {
                    }
            );
            return response.getBody();
        } catch (RestClientException e) {
            log.error("获取Grafana仪表板列表失败", e);
            return Collections.emptyList();
        }
    }

    public Map<String, Object> getGrafanaDashboard(String uid) {
        try {
            HttpHeaders headers = new HttpHeaders();
            headers.set("Authorization", "Bearer " + monitorConfig.getGrafana().getApiKey());
            String url = monitorConfig.getGrafana().getUrl() + "/api/dashboards/uid/" + uid;
            ResponseEntity<Map> response = restTemplate.exchange(
                    url, HttpMethod.GET, new HttpEntity<>(headers), Map.class
            );
            return response.getBody();
        } catch (RestClientException e) {
            log.error("获取Grafana仪表板详情失败", e);
            return Collections.emptyMap();
        }
    }

    public Map<String, Object> getPrometheusMetrics(String query) {
        try {
            // 使用URL模板和占位符，让RestTemplate负责正确的URL编码
            String url = monitorConfig.getPrometheus().getUrl() + "/api/v1/query?query={promql}";
            return restTemplate.getForObject(url, Map.class, query);
        } catch (RestClientException e) {
            log.error("查询Prometheus指标失败: {}", query, e);
            throw new RuntimeException("查询Prometheus指标失败: " + e.getMessage(), e);
        }
    }

    private KubernetesClient getK8sClient() {
        Config config = new ConfigBuilder()
                .withMasterUrl(monitorConfig.getKubernetes().getMasterUrl())
                .withOauthToken(monitorConfig.getKubernetes().getToken())
                .withTrustCerts(true)
                .build();
        return new KubernetesClientBuilder().withConfig(config).build();
    }

    public List<Pod> getK8sPods() {
        try (KubernetesClient client = getK8sClient()) {
            return client.pods().inNamespace(monitorConfig.getKubernetes().getNamespace()).list().getItems();
        } catch (Exception e) {
            log.error("获取Kubernetes Pod列表失败", e);
            return Collections.emptyList();
        }
    }

    public List<Event> getK8sEvents() {
        try (KubernetesClient client = getK8sClient()) {
            return client.v1().events().inNamespace(monitorConfig.getKubernetes().getNamespace()).list().getItems();
        } catch (Exception e) {
            log.error("获取Kubernetes事件列表失败", e);
            return Collections.emptyList();
        }
    }

    public Map<String, Object> getFaultStatus() {
        Map<String, Object> response = new HashMap<>();
        List<Map<String, Object>> metrics = new ArrayList<>();
        boolean hasFault = false;
        StringBuilder faultDetails = new StringBuilder();

        // 重新加入所有检查
        checkNodeStatus(metrics, faultDetails);
        checkPodStatus(metrics, faultDetails);
        checkServiceStatus(metrics, faultDetails);
        checkCpuUsage(metrics, faultDetails);
        checkMemoryUsage(metrics, faultDetails);
        checkNetworkUsage(metrics, faultDetails); // 新增网络检查

        for (Map<String, Object> metric : metrics) {
            if ("error".equals(metric.get("status"))) {
                hasFault = true;
                // 不再提前退出，以便收集所有错误信息
            }
        }

        response.put("hasFault", hasFault);
        response.put("message", hasFault ? "集群检测到故障或资源超阈值" : "系统运行正常");
        response.put("details", faultDetails.toString().trim());
        response.put("metrics", metrics);
        response.put("lastUpdate", System.currentTimeMillis());
        response.put("refreshInterval", METRIC_COLLECTION_INTERVAL_MS);
        return response;
    }

    private void checkNodeStatus(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        try (KubernetesClient client = getK8sClient()) {
            List<io.fabric8.kubernetes.api.model.Node> nodes = client.nodes().list().getItems();
            long totalNodes = nodes.size();
            long readyNodes = nodes.stream().filter(node ->
                    node.getStatus().getConditions().stream()
                            .anyMatch(c -> "Ready".equals(c.getType()) && "True".equals(c.getStatus()))
            ).count();

            String value = String.format("%d / %d", readyNodes, totalNodes);
            String status = (readyNodes == totalNodes) ? "normal" : "error";
            String message = (readyNodes == totalNodes) ? "所有节点均处于就绪状态" : String.format("有 %d 个节点未就绪", totalNodes - readyNodes);

            if ("error".equals(status)) {
                faultDetails.append(message).append(". ");
            }
            metrics.add(Map.of("name", "节点状态", "value", value, "status", status, "threshold", "-", "message", message));
        } catch (Exception e) {
            addErrorMetric(metrics, "节点状态", "通过K8s API检查节点状态时出错: " + e.getMessage());
            faultDetails.append("检查节点状态时出错. ");
        }
    }

    private void checkPodStatus(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        try (KubernetesClient client = getK8sClient()) {
            // 获取所有命名空间的Pod
            List<Pod> pods = client.pods().inAnyNamespace().list().getItems();
            log.info("成功获取 {} 个Pod", pods.size());

            // 过滤异常状态的Pod
            long badPodsCount = pods.stream().filter(pod -> {
                String phase = getPodPhase(pod);
                return "Pending".equals(phase) || "Failed".equals(phase) || "Unknown".equals(phase);
            }).count();

            String status = (badPodsCount == 0) ? "normal" : "error";
            String message = (badPodsCount == 0) ? "未检测到异常状态的Pod" :
                    String.format("检测到 %d 个Pod状态异常", badPodsCount);

            if ("error".equals(status)) {
                faultDetails.append(message).append(". ");
            }
            metrics.add(Map.of("name", "Pod状态", "value", String.format("%d 个异常", badPodsCount),
                    "status", status, "threshold", "0", "message", message));
        } catch (Exception e) {
            log.error("通过K8s API检查Pod状态时出错", e);
            addErrorMetric(metrics, "Pod状态", "通过K8s API检查Pod状态时出错: " + e.getMessage());
            faultDetails.append("检查Pod状态时出错. ");
        }
    }

    private void checkServiceStatus(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        String[] services = {"kubernetes-apiservers", "kubernetes-nodes"}; // kubernetes-nodes 代表 kubelet
        for (String serviceJob : services) {
            String serviceName = serviceJob.replace("kubernetes-", "").replace("s", ""); // 美化名称
            try {
                String query = String.format("min(up{job=\"%s\"})", serviceJob);
                Map<String, Object> result = getPrometheusMetrics(query);
                double upStatus = extractSingleValue(result);

                if (upStatus == -1) {
                    addErrorMetric(metrics, serviceName + "状态", "无法获取 " + serviceName + " 状态 (无数据)");
                    faultDetails.append("无法获取 ").append(serviceName).append(" 状态. ");
                    continue;
                }

                if (upStatus == 0) {
                    String errorMessage = String.format("%s 服务异常", serviceName);
                    metrics.add(Map.of("name", serviceName + "状态", "value", "异常", "status", "error", "message", errorMessage));
                    faultDetails.append(errorMessage).append(". ");
                } else {
                    metrics.add(Map.of("name", serviceName + "状态", "value", "正常", "status", "normal", "message", ""));
                }
            } catch (Exception e) {
                addErrorMetric(metrics, serviceName + "状态", "检查 " + serviceName + " 状态时出错: " + e.getMessage());
                faultDetails.append("检查 ").append(serviceName).append(" 状态时出错. ");
            }
        }
    }

    private void checkCpuUsage(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        try {
            String cpuQuery = "1 - sum(increase(node_cpu_seconds_total{mode=\"idle\"}[10s])) by (instance)/sum(increase(node_cpu_seconds_total[10s])) by (instance)";
            Map<String, Object> cpuResult = getPrometheusMetrics(cpuQuery);
            log.info("PromQL CPU usage result: {}", cpuResult);
            if (cpuResult != null && cpuResult.containsKey("data")) {
                Map<String, Object> data = (Map<String, Object>) cpuResult.get("data");
                if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    Map<String, Object> valueMap = resultList.get(0);
                    List<Object> valuePair = (List<Object>) valueMap.get("value");
                    if (valuePair != null && valuePair.size() > 1) {
                        double avgCpu = Double.parseDouble(valuePair.get(1).toString()) * 100;
                        String status = avgCpu > 80 ? "error" : "normal";
                        String message = String.format("当前值: %.2f%%, 阈值: 70%%", avgCpu);
                        metrics.add(Map.of(
                                "name", "CPU平均使用率",
                                "value", String.format("%.2f%%", avgCpu),
                                "status", status,
                                "threshold", "80%",
                                "message", message
                        ));
                        if ("error".equals(status))
                            faultDetails.append(String.format("CPU平均使用率异常 (%.2f%%). ", avgCpu));
                        return;
                    }
                }
            }
            addErrorMetric(metrics, "CPU平均使用率", "未能获取到有效的CPU数据");
        } catch (Exception e) {
            addErrorMetric(metrics, "CPU平均使用率", "Prometheus查询CPU使用率异常: " + e.getMessage());
        }
    }

    private void checkMemoryUsage(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        try {
            String memQuery = "sum(node_memory_MemTotal_bytes - node_memory_MemAvailable_bytes) / sum(node_memory_MemTotal_bytes) * 100";
            Map<String, Object> memResult = getPrometheusMetrics(memQuery);
            log.info("PromQL Mem usage result: {}", memResult);
            if (memResult != null && memResult.containsKey("data")) {
                Map<String, Object> data = (Map<String, Object>) memResult.get("data");
                if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    Map<String, Object> valueMap = resultList.get(0);
                    List<Object> valuePair = (List<Object>) valueMap.get("value");
                    if (valuePair != null && valuePair.size() > 1) {
                        double avgMem = Double.parseDouble(valuePair.get(1).toString());
                        String status = avgMem > 85 ? "error" : "normal";
                        String message = String.format("当前值: %.2f%%, 阈值: 60%%", avgMem);
                        metrics.add(Map.of(
                                "name", "内存平均使用率",
                                "value", String.format("%.2f%%", avgMem),
                                "status", status,
                                "threshold", "85%",
                                "message", message
                        ));
                        if ("error".equals(status))
                            faultDetails.append(String.format("内存平均使用率异常 (%.2f%%). ", avgMem));
                        return;
                    }
                }
            }
            addErrorMetric(metrics, "内存平均使用率", "未能获取到有效的内存数据");
        } catch (Exception e) {
            addErrorMetric(metrics, "内存平均使用率", "Prometheus查询内存使用率异常: " + e.getMessage());
        }
    }

    private void checkNetworkUsage(List<Map<String, Object>> metrics, StringBuilder faultDetails) {
        try {
            String rxQuery = "sum(rate(node_network_receive_bytes_total[10s]))";
            String txQuery = "sum(rate(node_network_transmit_bytes_total[10s]))";
            Map<String, Object> rxResult = getPrometheusMetrics(rxQuery);
            Map<String, Object> txResult = getPrometheusMetrics(txQuery);
            log.info("PromQL Net RX: {}", rxResult);
            log.info("PromQL Net TX: {}", txResult);
            double rx = -1, tx = -1;
            if (rxResult != null && rxResult.containsKey("data")) {
                Map<String, Object> data = (Map<String, Object>) rxResult.get("data");
                if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    rx = 0;
                    for (Map<String, Object> valueMap : resultList) {
                        List<Object> valuePair = (List<Object>) valueMap.get("value");
                        if (valuePair != null && valuePair.size() > 1) {
                            rx += Double.parseDouble(valuePair.get(1).toString());
                        }
                    }
                }
            }
            if (txResult != null && txResult.containsKey("data")) {
                Map<String, Object> data = (Map<String, Object>) txResult.get("data");
                if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    tx = 0;
                    for (Map<String, Object> valueMap : resultList) {
                        List<Object> valuePair = (List<Object>) valueMap.get("value");
                        if (valuePair != null && valuePair.size() > 1) {
                            tx += Double.parseDouble(valuePair.get(1).toString());
                        }
                    }
                }
            }
            if (rx >= 0 && tx >= 0) {
                metrics.add(Map.of(
                        "name", "网络总接收速率",
                        "value", String.format("%.2f MB/s", rx / 1024 / 1024),
                        "status", "normal",
                        "threshold", "-",
                        "message", ""
                ));
                metrics.add(Map.of(
                        "name", "网络总发送速率",
                        "value", String.format("%.2f MB/s", tx / 1024 / 1024),
                        "status", "normal",
                        "threshold", "-",
                        "message", ""
                ));
            } else {
                metrics.add(Map.of(
                        "name", "网络速率",
                        "value", "采集中",
                        "status", "normal",
                        "threshold", "-",
                        "message", "等待数据以计算速率"
                ));
            }
        } catch (Exception e) {
            metrics.add(Map.of(
                    "name", "网络速率",
                    "value", "查询失败",
                    "status", "error",
                    "threshold", "-",
                    "message", "Prometheus查询网络速率异常: " + e.getMessage()
            ));
        }
    }

    private void processResourceMetric(List<Map<String, Object>> metrics, Map<String, Object> result, String name, double threshold, StringBuilder faultDetails) {
        log.info("Processing resource metric '{}'. Raw Prometheus result: {}", name, result);
        if (result != null && result.containsKey("data")) {
            Map<String, Object> data = (Map<String, Object>) result.get("data");
            if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                Map<String, Object> valueMap = resultList.get(0);
                List<Object> valuePair = (List<Object>) valueMap.get("value");
                if (valuePair != null && valuePair.size() > 1) {
                    double displayValue = Double.parseDouble(valuePair.get(1).toString());
                    String status = displayValue > threshold ? "error" : "normal";
                    String message = String.format("当前值: %.2f%%, 阈值: %.0f%%", displayValue, threshold);
                    if ("error".equals(status)) {
                        faultDetails.append(String.format("%s异常 (%.2f%%). ", name, displayValue));
                    }
                    metrics.add(Map.of(
                            "name", name,
                            "value", String.format("%.2f%%", displayValue),
                            "status", status,
                            "threshold", String.format("%.0f%%", threshold),
                            "message", message
                    ));
                    return;
                }
            }
        }
        addErrorMetric(metrics, name, "未能获取到有效的 " + name + " 数据，可能是因为 node-exporter 未安装或配置不正确。");
    }

    private void addErrorMetric(List<Map<String, Object>> metrics, String name, String message) {
        metrics.add(Map.of(
                "name", name,
                "value", "查询失败",
                "status", "error",
                "threshold", "-",
                "message", message
        ));
    }

    private double extractSingleValue(Map<String, Object> result) {
        if (result != null && result.containsKey("data")) {
            Map<String, Object> data = (Map<String, Object>) result.get("data");
            if (data.get("result") instanceof List && !((List) data.get("result")).isEmpty()) {
                List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                Map<String, Object> valueMap = resultList.get(0);
                List<Object> valuePair = (List<Object>) valueMap.get("value");
                if (valuePair != null && valuePair.size() > 1) {
                    return Double.parseDouble(valuePair.get(1).toString());
                }
            }
        }
        return -1; // 表示未找到或格式错误
    }

    @Scheduled(fixedRate = METRIC_COLLECTION_INTERVAL_MS)
    public void collectRawMetrics() {
        collectCpuData();
        collectNetworkData();
    }

    private void collectCpuData() {
        try {
            String cpuQuery = "node_cpu_seconds_total";
            Map<String, Object> cpuResult = getPrometheusMetrics(cpuQuery);
            log.info("Collected CPU data from Prometheus: {}", cpuResult);
            CpuSample newSample = new CpuSample();
            newSample.timestamp = System.currentTimeMillis();
            if (cpuResult != null && cpuResult.containsKey("data")) {
                Map<String, Object> data = (Map<String, Object>) cpuResult.get("data");
                if (data.get("result") instanceof List) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    for (Map<String, Object> valueMap : resultList) {
                        Map<String, String> metric = (Map<String, String>) valueMap.get("metric");
                        String instance = metric.getOrDefault("instance", "default");
                        String cpu = metric.getOrDefault("cpu", "0");
                        String mode = metric.getOrDefault("mode", "idle");
                        List<Object> valuePair = (List<Object>) valueMap.get("value");
                        if (valuePair != null && valuePair.size() > 1) {
                            double val = Double.parseDouble(valuePair.get(1).toString());
                            newSample.instanceCpuModeValue
                                    .computeIfAbsent(instance, k -> new HashMap<>())
                                    .computeIfAbsent(cpu, k -> new HashMap<>())
                                    .put(mode, val);
                        }
                    }
                }
            }
            synchronized (this) {
                cpuSamples[0] = cpuSamples[1];
                cpuSamples[1] = newSample;
            }
        } catch (Exception e) {
            log.error("定时采集CPU原始数据失败", e);
        }
    }

    private void collectNetworkData() {
        try {
            String rxQuery = "node_network_receive_bytes_total";
            String txQuery = "node_network_transmit_bytes_total";
            Map<String, Object> rxResult = getPrometheusMetrics(rxQuery);
            Map<String, Object> txResult = getPrometheusMetrics(txQuery);
            log.info("Collected RX data from Prometheus: {}", rxResult);
            log.info("Collected TX data from Prometheus: {}", txResult);

            synchronized (this) {
                // 采集接收流量
                if (rxResult != null && rxResult.containsKey("data")) {
                    Map<String, Object> data = (Map<String, Object>) rxResult.get("data");
                    if (data.get("result") instanceof List) {
                        List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                        for (Map<String, Object> valueMap : resultList) {
                            Map<String, String> metric = (Map<String, String>) valueMap.get("metric");
                            String instance = metric.getOrDefault("instance", "default");
                            List<Object> valuePair = (List<Object>) valueMap.get("value");
                            if (valuePair != null && valuePair.size() > 1) {
                                double val = Double.parseDouble(valuePair.get(1).toString());
                                Double[] arr = netRxCache.getOrDefault(instance, new Double[]{null, null});
                                arr[0] = arr[1];
                                arr[1] = val;
                                netRxCache.put(instance, arr);
                            }
                        }
                    }
                }
                // 采集发送流量
                if (txResult != null && txResult.containsKey("data")) {
                    Map<String, Object> data = (Map<String, Object>) txResult.get("data");
                    if (data.get("result") instanceof List) {
                        List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                        for (Map<String, Object> valueMap : resultList) {
                            Map<String, String> metric = (Map<String, String>) valueMap.get("metric");
                            String instance = metric.getOrDefault("instance", "default");
                            List<Object> valuePair = (List<Object>) valueMap.get("value");
                            if (valuePair != null && valuePair.size() > 1) {
                                double val = Double.parseDouble(valuePair.get(1).toString());
                                Double[] arr = netTxCache.getOrDefault(instance, new Double[]{null, null});
                                arr[0] = arr[1];
                                arr[1] = val;
                                netTxCache.put(instance, arr);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("定时采集网络原始数据失败", e);
        }
    }

    public String getKubectlStatus(Pod pod) {
        PodStatus status = pod.getStatus();
        String phase = status.getPhase();

        if (pod.getMetadata().getDeletionTimestamp() != null) {
            return "Terminating";
        }

        List<ContainerStatus> initContainerStatuses = status.getInitContainerStatuses();
        if (initContainerStatuses != null && !initContainerStatuses.isEmpty()) {
            for (int i = 0; i < initContainerStatuses.size(); i++) {
                ContainerStatus cs = initContainerStatuses.get(i);
                if (cs.getState().getTerminated() != null && cs.getState().getTerminated().getExitCode() != 0) {
                    return "Init:Error";
                }
                if (cs.getState().getWaiting() != null) {
                    return "Init:" + cs.getState().getWaiting().getReason();
                }
            }
        }

        List<ContainerStatus> containerStatuses = status.getContainerStatuses();
        if (containerStatuses != null && !containerStatuses.isEmpty()) {
            int readyCount = 0;
            for (ContainerStatus cs : containerStatuses) {
                if (cs.getReady()) {
                    readyCount++;
                } else {
                    if (cs.getState().getWaiting() != null) {
                        return cs.getState().getWaiting().getReason();
                    }
                    if (cs.getState().getTerminated() != null) {
                        return cs.getState().getTerminated().getReason();
                    }
                }
            }
            if (readyCount == containerStatuses.size()) {
                return "Running";
            }
        }

        return phase;
    }

    public List<Map<String, Object>> getK8sPodsDetail() {
        try (KubernetesClient client = getK8sClient()) {
            String namespace = monitorConfig.getKubernetes().getNamespace();
            List<Pod> pods = (namespace == null || namespace.isEmpty())
                    ? client.pods().inAnyNamespace().list().getItems()
                    : client.pods().inNamespace(namespace).list().getItems();

            log.info("成功获取 {} 个Pod，命名空间: {}", pods.size(),
                    (namespace == null) ? "所有命名空间" : namespace);

            List<Map<String, Object>> result = new ArrayList<>();
            for (Pod pod : pods) {
                result.add(Map.of(
                        "name", getPodName(pod),
                        "namespace", getPodNamespace(pod),
                        "status", getKubectlStatus(pod),
                        "phase", getPodPhase(pod),
                        "message", pod.getStatus().getMessage() != null ? pod.getStatus().getMessage() : ""
                ));
            }
            return result;
        } catch (Exception e) {
            log.error("获取Kubernetes Pod详细信息失败", e);
            throw new RuntimeException("获取Kubernetes Pod详细信息失败", e);
        }
    }

    private String getPodName(Pod pod) {
        return (pod != null && pod.getMetadata() != null) ? pod.getMetadata().getName() : "unknown-pod";
    }

    private String getPodNamespace(Pod pod) {
        return (pod != null && pod.getMetadata() != null) ? pod.getMetadata().getNamespace() : "unknown-namespace";
    }

    private String getPodPhase(Pod pod) {
        return (pod != null && pod.getStatus() != null) ? pod.getStatus().getPhase() : "Unknown";
    }

    /**
     * 【已修改】获取详细Node信息，聚合K8s和Prometheus数据
     */
    public List<Map<String, Object>> getK8sNodesDetail() {
        try (KubernetesClient client = getK8sClient()) {
            // 1. 从K8s API获取节点基本信息
            List<io.fabric8.kubernetes.api.model.Node> nodes = client.nodes().list().getItems();
            List<Map<String, Object>> nodeDetailsList = new ArrayList<>();

            for (io.fabric8.kubernetes.api.model.Node node : nodes) {
                Map<String, Object> details = new LinkedHashMap<>(); // 使用LinkedHashMap保持顺序
                ObjectMeta metadata = node.getMetadata();
                NodeStatus nodeStatus = node.getStatus();

                // 基本信息
                details.put("name", metadata.getName());
                details.put("creationTimestamp", metadata.getCreationTimestamp());

                // 状态和条件
                boolean isReady = nodeStatus.getConditions().stream()
                        .anyMatch(c -> "Ready".equals(c.getType()) && "True".equals(c.getStatus()));
                details.put("status", isReady ? "normal" : "abnormal");
                details.put("conditions", nodeStatus.getConditions());

                // 从标签中提取角色
                List<String> roles = metadata.getLabels().keySet().stream()
                        .filter(key -> key.startsWith("node-role.kubernetes.io/"))
                        .map(key -> key.substring(key.indexOf("/") + 1))
                        .collect(Collectors.toList());
                if (metadata.getLabels().containsKey("node-role.kubernetes.io/master") || metadata.getLabels().containsKey("node-role.kubernetes.io/control-plane")){
                    if (!roles.contains("master")) {
                        roles.add("master");
                    }
                }
                if (roles.isEmpty()) {
                    roles.add("worker"); // 如果没有特定角色标签，默认为worker
                }
                details.put("roles", roles);

                // 节点系统信息
                if (nodeStatus.getNodeInfo() != null) {
                    NodeSystemInfo nodeInfo = nodeStatus.getNodeInfo();
                    details.put("kubeletVersion", nodeInfo.getKubeletVersion());
                    details.put("osImage", nodeInfo.getOsImage());
                    details.put("containerRuntimeVersion", nodeInfo.getContainerRuntimeVersion());
                    details.put("architecture", nodeInfo.getArchitecture());
                }

                // IP 地址
                nodeStatus.getAddresses().forEach(address -> {
                    if ("InternalIP".equals(address.getType())) {
                        details.put("internalIp", address.getAddress());
                    }
                    if ("ExternalIP".equals(address.getType())) {
                        details.put("externalIp", address.getAddress());
                    }
                });

                // 资源容量
                Map<String, Quantity> capacity = nodeStatus.getCapacity();
                details.put("cpuCapacity", capacity.get("cpu").toString());
                details.put("memoryCapacity", capacity.get("memory").toString());
                details.put("podCapacity", capacity.get("pods").toString());

                // 初始化资源使用率
                details.put("cpuUsage", 0.0);
                details.put("memoryUsage", 0.0);

                nodeDetailsList.add(details);
            }

            // 2. 从Prometheus获取资源使用率
            Map<String, Double> cpuUsages = getPerNodeMetrics("100 - (avg by (instance) (rate(node_cpu_seconds_total{mode=\"idle\"}[1m])) * 100)");
            Map<String, Double> memoryUsages = getPerNodeMetrics("100 * (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes))");

            // 3. 将Prometheus数据合并到节点信息中
            for (Map<String, Object> nodeDetails : nodeDetailsList) {
                String internalIp = (String) nodeDetails.get("internalIp");
                if (internalIp != null) {
                    // 通过IP地址匹配instance
                    cpuUsages.entrySet().stream()
                            .filter(entry -> entry.getKey().startsWith(internalIp + ":"))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .ifPresent(usage -> nodeDetails.put("cpuUsage", usage));

                    memoryUsages.entrySet().stream()
                            .filter(entry -> entry.getKey().startsWith(internalIp + ":"))
                            .map(Map.Entry::getValue)
                            .findFirst()
                            .ifPresent(usage -> nodeDetails.put("memoryUsage", usage));
                }
            }

            return nodeDetailsList;
        } catch (Exception e) {
            log.error("获取Kubernetes Node详细信息失败", e);
            return Collections.emptyList();
        }
    }

    /**
     * 新增：用于查询Prometheus per-node指标的辅助方法
     * @param query PromQL查询语句
     * @return Map<String, Double> 其中key是instance, value是指标值
     */
    private Map<String, Double> getPerNodeMetrics(String query) {
        Map<String, Double> usageMap = new HashMap<>();
        try {
            Map<String, Object> promResult = getPrometheusMetrics(query);
            if (promResult != null && "success".equals(promResult.get("status")) && promResult.get("data") instanceof Map) {
                Map<String, Object> data = (Map<String, Object>) promResult.get("data");
                if (data.get("result") instanceof List) {
                    List<Map<String, Object>> resultList = (List<Map<String, Object>>) data.get("result");
                    for (Map<String, Object> item : resultList) {
                        Map<String, String> metric = (Map<String, String>) item.get("metric");
                        String instance = metric.get("instance");
                        List<Object> valuePair = (List<Object>) item.get("value");
                        if (instance != null && valuePair != null && valuePair.size() > 1) {
                            try {
                                double value = Double.parseDouble(valuePair.get(1).toString());
                                usageMap.put(instance, value);
                            } catch (NumberFormatException e){
                                log.warn("无法解析Prometheus指标值: {}", valuePair.get(1));
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("查询Prometheus per-node指标失败: query={}, error={}", query, e.getMessage());
        }
        return usageMap;
    }
}